﻿#include "udpclient.h"

#include <QIODevice>
#include <QJsonObject>
#include <QJsonDocument>
#include <QMetaType>

UdpClient::UdpClient(QObject* parent)
    :QObject(parent)
{
    qRegisterMetaType<PluginJsonData>("PluginJsonData");
    qRegisterMetaType<PluginJsonErrorData>("PluginJsonErrorData");


    socket_ = new QUdpSocket(this);

#if QT_VERSION < QT_VERSION_CHECK(5,15,0)
    connect(socket_,static_cast<void(QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error),
            [=](QAbstractSocket::SocketError err){
        QString log = QString("网络异常: %1").arg(err);
        emit sendMessage("网络异常");
    });
#else
    connect(socket_,
            static_cast<void(QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::errorOccurred),
            [=](QAbstractSocket::SocketError err){
        QString log = QString("网络异常: %1").arg(err);
#ifdef TestCode
        log_file_->write(log.toLocal8Bit());
        log_file_->write("\n");
#endif
        emit sendMessage("网络异常");
    });
#endif
    connect(socket_, &QUdpSocket::readyRead,[this](){
        RecvDataFromNetwork();
    });
}

UdpClient::~UdpClient()
{
    socket_->abort();
    delete socket_;
}

void UdpClient::bindNetwork(const QString& ip,const int port)
{
    qDebug() << ip << port;
    socket_->abort();
    if(!socket_->bind(QHostAddress(ip),port,QUdpSocket::ShareAddress)){
        return;
    }

    emit sendMessage("网络正常");
    is_abort = false;
}

void UdpClient::abortNetword()
{
    socket_->abort();
    is_abort = true;
    emit sendMessage("网络已关闭");
}

void UdpClient::RecvDataFromNetwork()
{
    array_cache_.clear();
    while(socket_->hasPendingDatagrams())
    {
        array_cache_.resize(static_cast<int>(socket_->pendingDatagramSize()));
        socket_->readDatagram(array_cache_.data(), array_cache_.size());
        //qDebug() << array_cache_.toHex() << array_cache_.size();
        ParseAndPutData(array_cache_);
    }
}

void UdpClient::ParseAndPutData(QByteArray& data)
{
    //qDebug() << QString::fromUtf8(data);

    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(data,&parseError);
    if(doc.isNull() || parseError.error != QJsonParseError::NoError){
        return;
    }

    PluginJsonData pluginJsonData;
    PluginJsonErrorData pluginJsonErrorData;
    QJsonValue pluginData;
    QString command;
    if(doc.isObject()){
        auto objRoot = doc.object();
        if(objRoot.contains("pluginName")){
            pluginJsonData.pluginName = objRoot.value("pluginName").toString();
        }

        if(objRoot.contains("pluginNameCN")){
            pluginJsonData.pluginNameCN = objRoot.value("pluginNameCN").toString();
        }

        if(objRoot.contains("appName")){
            pluginJsonData.appName = objRoot.value("appName").toString();
        }

        if(objRoot.contains("command")){
            command = objRoot.value("command").toString();
        }

        if(objRoot.contains("data")){
            pluginData = objRoot.value("data");
        }
    }

    if(command == "error" && !pluginData.isNull()){
        if(pluginData.isObject()){
            auto errorRoot = pluginData.toObject();
            if(errorRoot.contains("type")){
                pluginJsonErrorData.type = errorRoot.value("type").toString();
            }

            if(errorRoot.contains("msg")){
                pluginJsonErrorData.msg = errorRoot.value("msg").toString();
            }

            if(errorRoot.contains("file")){
                pluginJsonErrorData.file = errorRoot.value("file").toString();
            }

            if(errorRoot.contains("name")){
                pluginJsonErrorData.func = errorRoot.value("name").toString();
            }

            if(errorRoot.contains("line")){
                pluginJsonErrorData.line = errorRoot.value("line").toInt();
            }
        }
        emit sendPluginData(PluginCommand::error,pluginJsonData.pluginName,QVariant::fromValue(pluginJsonErrorData));
    }else if(command == "begin"){
        emit sendPluginData(PluginCommand::begin,pluginJsonData.pluginName,QVariant::fromValue(pluginJsonData));
    }else if(command == "end"){
        emit sendPluginData(PluginCommand::end,pluginJsonData.pluginName,QVariant::fromValue(pluginJsonData));
    }else if(command == "progress" && !pluginData.isNull()){
        emit sendPluginData(PluginCommand::progress,pluginJsonData.pluginName,pluginData.toInt());
    }else if(command == "log" && !pluginData.isNull()){
        emit sendPluginData(PluginCommand::log,pluginJsonData.pluginName,QVariant::fromValue(pluginData.toString()));
    }else if(command == "showpic"){
        emit sendPluginData(PluginCommand::showpic,pluginJsonData.pluginName,QVariant::fromValue(pluginData.toString()));
    }
}
